/*
    BibleNotebook - A bible reader software
    Copyright (C) 2014  Williams Fernando Lopez

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
 */

/*
 * MainPanel.java
 * Created on 8/07/2013, 11:15:16 AM
 */

package com.simplebible.ui.components;

import wl.ui.CustomLayoutPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import com.simplebible.bible.BibleReader;
import com.simplebible.bible.BibleUtils;
import wl.util.TextResourcesUtil;
import wl.util.Utils;
import com.simplebible.bible.objects.Abreviation;
import com.simplebible.bible.objects.Bible;
import com.simplebible.bible.objects.BookMark;
import com.simplebible.bible.objects.BookMarkGroup;
import com.simplebible.objects.Preferences;
import com.simplebible.ui.Events;

/**
 *
 * @author Williams Lopez
 */
public class MainPanel extends javax.swing.JPanel {

    private static NotificationPane notifPane = new NotificationPane();
    private JFrame mainFrame = null;

    private ReaderPanel reader1 = null;
    private ReaderPanel reader2 = null;
    private BookmarkPanel bookmarkPanel = null;
    private VerseQuickOptionPane verseQuickOptions = null;
    private NotePanel notePanel = null;
    private DictionariesPanel dictionaryPanel = null;
    private GeneralConfigPanel generalConfig;



    /** Creates new form MainPanel */
    public MainPanel() {
        initComponents();
        try{
            TextResourcesUtil.registrarComponente(this);
        }catch(Exception e){
            Utils.printToLog("Error al setear los textos. ", e,Preferences.LOG_LEVEL_ERROR);
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                notifPane.setLocation(labelViewMode,-(int)notifPane.getPreferredSize().getWidth(), -(int)notifPane.getPreferredSize().getHeight());
            }
        });

        buildGeneralConfig();
        buildVerseQuickOptions();
        setVisibleDualPanel(false);
        CustomLayoutPane panel = (CustomLayoutPane) jPanel1;
        if (Preferences.getInst().isHorizontalLayout()) {
            panel.setOrientation(CustomLayoutPane.HORIZONTAL);
        } else {
            panel.setOrientation(CustomLayoutPane.VERTICAL);
        }
    }

    public BookmarkPanel getBookmarkPanel() {
        return bookmarkPanel;
    }

    public DictionariesPanel getDictionaryPanel() {
        return dictionaryPanel;
    }

    public ReaderPanel getReader1() {
        return reader1;
    }

    public ReaderPanel getReader2() {
        return reader2;
    }

    public NotePanel getNotePanel(){
        return notePanel;
    }



    public void setMainFrame(JFrame f){
        this.mainFrame = f;
    }

    
    public static NotificationPane getNotifPane(){

        if(notifPane==null){
            notifPane = new NotificationPane();
        }else{
            notifPane.clear();
        }
        
        return notifPane;
    }

    public static void showYesNoCancelQuestion(String shortDesc,YesNoCancelListener evento){

        NotificationPane notifPane = MainPanel.getNotifPane();
        final String textShort = TextResourcesUtil.getText(shortDesc);
        final String textLong  = TextResourcesUtil.getText(shortDesc+"_long");

        try {
            notifPane.addYesNoCancelListener(evento);
            notifPane.show(textShort, textLong, NotificationPane.TYPE_QUESTION);
        } catch (Exception err) {
            Utils.printToLog("No se puede mostrar el panel de notificacion", err, Preferences.LOG_LEVEL_ERROR);
        }
    }

    public static void showNotification(String shortDesc,Exception e,int type){

        NotificationPane notifPane = MainPanel.getNotifPane();

        String textShort = TextResourcesUtil.getText(shortDesc);
        String textLong  = TextResourcesUtil.getText(shortDesc+"_long");


        if(textShort == null){
            textShort = shortDesc;
            textLong = shortDesc;
        }


        if(e!=null){
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try{
                PrintWriter pw = new PrintWriter(baos);
                e.printStackTrace(pw);
                pw.flush();
                baos.close();
            }catch(Exception ex){
                Utils.printToLog("Error al generar el strack trace para el usuario", ex, Preferences.LOG_LEVEL_ERROR);
            }
            try{
                notifPane.show(textShort, textLong + "\n" + baos.toString(), NotificationPane.TYPE_ERROR);
            }catch(Exception err){
                Utils.printToLog("No se puede mostrar el panel de notificacion", err, Preferences.LOG_LEVEL_ERROR);
            }
        }else{
            try{

                notifPane.show(textShort, textLong, type);
            }catch(Exception err){
                Utils.printToLog("No se puede mostrar el panel de notificacion", err, Preferences.LOG_LEVEL_ERROR);
            }
        }
    }

    public static void hideNotification(){
        MainPanel.getNotifPane().setVisible(false);
    }

    public static void showNotification(String shortDesc,Exception e){
        showNotification(shortDesc,e,NotificationPane.TYPE_INFO);
    }

    //VISIBILITI OF PANELS
    public void setSincEnable(boolean enable){
        if(enable){
            labelSinc.setEnabled(true);
            reader1.setDualPanel(reader2);
        }else{
            labelSinc.setEnabled(false);
            reader1.setDualPanel(null);
        }
    }

    public void setVisibleBookMarkPanel(boolean visible){
        if(bookmarkPanel == null){
            bookmarkPanel =new BookmarkPanel();
            bookmarkPanel.addBookmarkPanelListener(new BookmarkPanelListener() {
                public void groupSelected(BookMarkGroup e) {}
                public void groupEliminated(BookMarkGroup e, boolean exitoso) {}
                public void bookMarkSelected(BookMark e) {
                    try{
                        reader1.setCapitulo(e.getAbreviation());
                    }catch(Exception ex){
                        showNotification("generic_error", ex);
                    }
                }
                public void bookMarkEliminated(BookMark e, boolean exitoso) {}
                public void bookMarkEliminatedFromGroup(BookMark e, BookMarkGroup g, boolean exitoso) {}
            });
        }
        if (visible) {
            labelBookmark.setEnabled(true);
            bookmarkPanel.setCurrentBible(reader1.getCurrentBible());
            bookmarkPanel.refresh();
            this.jPanel1.add(bookmarkPanel);
        }else{
            labelBookmark.setEnabled(false);
            jPanel1.remove(bookmarkPanel);
        }
        
        this.updateUI();
    }

    public void setVisibleDualPanel(boolean visible){

        labelViewMode.setEnabled(visible);

        if (visible) {
            if (reader2 == null) {
                reader2 = new ReaderPanel();
                reader2.setVerseOptionPanel(verseQuickOptions);
            }
            this.jPanel1.add(reader2);
            this.labelSinc.setVisible(true);
            setSincEnable(this.labelSinc.isEnabled());
        } else {
            if (reader1 == null) {
                reader1 = new ReaderPanel();
                reader1.setVerseOptionPanel(verseQuickOptions);
                this.jPanel1.add(reader1);
            }
            if (reader2 != null) {
                this.jPanel1.remove(reader2);
            }
            this.labelSinc.setVisible(false);
        }

        this.updateUI();
    }

    public void setVisibleNotePanel(boolean visible){

        labelNote.setEnabled(visible);
        if(!visible){
            //hide
            jPanel1.remove(getNotePanelInstance());
            this.updateUI();
        }else{
            //show
            jPanel1.add(getNotePanelInstance());
            getNotePanelInstance().requestFocus();
        }
        this.updateUI();
    }

    public void setVisibleDictionaryPanel(boolean visible){
        labelDictionary.setEnabled(visible);
        if(visible){
            if(dictionaryPanel==null){
                dictionaryPanel = new DictionariesPanel();
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        dictionaryPanel.setDictionaryRootMenuBackground();
                    }
                });
            }
            jPanel1.add(dictionaryPanel);
        }else{
            if(dictionaryPanel == null){
                return;
            }
            jPanel1.remove(dictionaryPanel);
        }
        this.updateUI();
    }
    
    //TOOGLES FOR PANELS
    public void toogleEnableSinc(){
        setSincEnable(!labelSinc.isEnabled());
    }
    
    public void toogleBookMarkPanel(){
        setVisibleBookMarkPanel(!labelBookmark.isEnabled());
    }
    
    public void toogleDualPanel(){
        setVisibleDualPanel(!labelViewMode.isEnabled());
    }

    public void toogleNotePanel(){
        setVisibleNotePanel(!labelNote.isEnabled());
    }
    
    public void toogleDictionaryPanel(){
        setVisibleDictionaryPanel(!labelDictionary.isEnabled());
    }


    public void showGeneralConfig(){
        generalConfig.show(this.labelConfig, 0, -50);
    }

    public void nextChapter(){
        if(reader1!=null){
            reader1.nextChapter();
        }
    }

    public void prevChapter(){
        if(reader1!=null){
            reader1.previousChapter();
        }
    }

    public void showSelectVersePanel(){
        if(reader1!=null){
            reader1.showSelector();
        }
    }

    public void showConfigVersionPanel(){
        if(reader1!=null){
            reader1.showConfigPanel();
        }
    }


    /******************************** PRIVATE METHODS *****************************************/

    private void buildGeneralConfig(){
        generalConfig = new GeneralConfigPanel();
        generalConfig.setChangeIdiomaListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    if(e.getSource()!=null && e.getSource() instanceof  String){
                        TextResourcesUtil.cambiarIdioma((String)e.getSource());
                    }
                } catch (Exception ex) {
                    MainPanel.showNotification("error_cambiando_idioma", ex);
                }
            }
        });
        generalConfig.setEnableAnimacionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    if(e.getSource()!=null && e.getSource() instanceof  Boolean){
                        boolean b = (Boolean)e.getSource();
                        Preferences.getInst().setAnimation(b);
                        if(reader1!=null) reader1.setAnimationEnable(b);
                        if(reader2!=null) reader2.setAnimationEnable(b);
                    }
                } catch (Exception ex) {
                    showNotification("error_habilitar_animacion", ex);
                }
            }
        });
        generalConfig.setEnableDisableHorizontalLayout(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    if(e.getSource()!=null && e.getSource() instanceof  Boolean){
                        boolean b = (Boolean)e.getSource();
                        Preferences.getInst().setHorizontalLayout(b);
                        CustomLayoutPane panel = (CustomLayoutPane)jPanel1;
                        if(b){
                            panel.setOrientation(CustomLayoutPane.HORIZONTAL);
                        }else{
                            panel.setOrientation(CustomLayoutPane.VERTICAL);
                        }
                    }
                } catch (Exception ex) {
                    showNotification("generic_error", ex);
                }
            }
        });
    }

    private void buildVerseQuickOptions(){
        verseQuickOptions = new VerseQuickOptionPane();
         verseQuickOptions.addMarcadorListener(new VerseQuickOptionListener() {
            public void action(Abreviation abrv, String command, Object other) {
                if(abrv!=null){
                    try{
                        Bible b = BibleReader.getBible(abrv.getBible());
                        setVisibleBookMarkPanel(true);
                        bookmarkPanel.showNewMarcador(b, abrv);
                    }catch(Exception e){
                        showNotification("error_agregar_marcador", e);
                        Utils.printToLog("Error al agregar el marcador", e, Preferences.LOG_LEVEL_ERROR);
                    }
                }
            }
        });

        verseQuickOptions.addNoteListener(new VerseQuickOptionListener() {
            public void action(Abreviation abrv, String command, Object other) {
                if(abrv!=null){
                    try{
                        showNotePanel(abrv);
                    }catch(Exception e){
                        showNotification("error_agregar_marcador", e);
                        Utils.printToLog("Error al agregar el marcador", e, Preferences.LOG_LEVEL_ERROR);
                    }
                }
            }
        });

        verseQuickOptions.addWordListener(new VerseQuickOptionListener() {
            public void action(Abreviation abrv, String command, Object other) {
                if(abrv!=null && command!=null){
                    try{
                        setVisibleDictionaryPanel(true);
                        dictionaryPanel.setWordDefinitions(command);
                    }catch(Exception e){
                        showNotification("generic_error", e);
                        Utils.printToLog("Error al mostrar la palabra en el diccionario", e, Preferences.LOG_LEVEL_ERROR);
                    }
                }
            }
        });
    }

    private void showNotePanel(Abreviation abrv){
        try {
            setVisibleNotePanel(true);
            
            Bible b = BibleReader.getBible(abrv.getBible());
            if(!getNotePanelInstance().isFileOpen()){
                getNotePanelInstance().showNewNote(b,abrv);
            }else{
                getNotePanelInstance().showOpenNote();
                getNotePanelInstance().addVerseToNote(b, abrv);
            }
        } catch (Exception e) {
            MainPanel.showNotification("generic_error", e);
            Utils.printToLog("Error al mostrar o agregar la nota", e, Preferences.LOG_LEVEL_ERROR);
        }
    }
    
    private NotePanel getNotePanelInstance(){
        if(notePanel == null){
            notePanel = new NotePanel();

            notePanel.getEditor().addHyperlinkListener(new HyperlinkListener() {
                public void hyperlinkUpdate(HyperlinkEvent e) {
                    try {
                        String url = e.getDescription();
                        String action = url.substring(0, url.indexOf(":"));
                        String value = url.substring(url.indexOf(":") + 1, url.length());
                        if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
                            if (action.equalsIgnoreCase("verse")) {
                                reader1.setCapitulo(Abreviation.parse(value));
                            }
                        }
                    } catch (Exception ex) {
                        showNotification("generic_error", ex);
                    }
                }
            });

        }
        return notePanel;
    }

    public void finish() {
        if(notePanel!=null){
            notePanel.save();
        }
        Preferences.getInst().save();
    }

    public void refresh(){
        if(reader1!=null) reader1.refreshAll();
        if(reader2!=null) reader2.refreshAll();
        if(bookmarkPanel!=null) bookmarkPanel.refresh();
        //notePanel.refresh()
        //generalConfig.refresh()
    }


    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new CustomLayoutPane();
        labelNote = new wl.ui.ButtonLabel();
        labelBookmark = new wl.ui.ButtonLabel();
        labelSinc = new wl.ui.ButtonLabel();
        labelViewMode = new wl.ui.ButtonLabel();
        labelConfig = new wl.ui.ButtonLabel();
        labelDictionary = new wl.ui.ButtonLabel();

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createTitledBorder(""));

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.X_AXIS));

        labelNote.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/note_add.png"))); // NOI18N
        labelNote.setToolTipText("Abrir notas");
        labelNote.setEnabled(false);
        labelNote.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelNoteActionPerformed(evt);
            }
        });

        labelBookmark.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/bookmark.png"))); // NOI18N
        labelBookmark.setToolTipText("Ver marcadores");
        labelBookmark.setEnabled(false);
        labelBookmark.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelBookmarkActionPerformed(evt);
            }
        });

        labelSinc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/Synchronize.png"))); // NOI18N
        labelSinc.setToolTipText("Sincronizar biblias en paralelo");
        labelSinc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelSincActionPerformed(evt);
            }
        });

        labelViewMode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/column_double.png"))); // NOI18N
        labelViewMode.setToolTipText("Vista en paralelo");
        labelViewMode.setEnabled(false);
        labelViewMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelViewModeActionPerformed(evt);
            }
        });

        labelConfig.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/1372829957_cog_edit.png"))); // NOI18N
        labelConfig.setToolTipText("Configuración general");
        labelConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelConfigActionPerformed(evt);
            }
        });

        labelDictionary.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/dictionary.png"))); // NOI18N
        labelDictionary.setEnabled(false);
        labelDictionary.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                labelDictionaryActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(labelConfig, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 520, Short.MAX_VALUE)
                .addComponent(labelDictionary, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(labelNote, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(labelBookmark, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(labelSinc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(labelViewMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(2, 2, 2))
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 738, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(labelDictionary, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labelViewMode, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labelSinc, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labelBookmark, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labelNote, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labelConfig, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void labelNoteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelNoteActionPerformed
        Events.execute(Events.TOOGLE_NOTE_PANEL, this);
    }//GEN-LAST:event_labelNoteActionPerformed

    private void labelBookmarkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelBookmarkActionPerformed
        Events.execute(Events.TOOGLE_BOOKMARK_PANEL, this);
    }//GEN-LAST:event_labelBookmarkActionPerformed

    private void labelSincActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelSincActionPerformed
        Events.execute(Events.TOOGLE_SINCRONIZATION, this);
    }//GEN-LAST:event_labelSincActionPerformed

    private void labelViewModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelViewModeActionPerformed
        Events.execute(Events.TOOGLE_PARALLEL_VIEW, this);
    }//GEN-LAST:event_labelViewModeActionPerformed

    private void labelConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelConfigActionPerformed
        Events.execute(Events.SHOW_GENERAL_CONFIG, this);
    }//GEN-LAST:event_labelConfigActionPerformed

    private void labelDictionaryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_labelDictionaryActionPerformed
        Events.execute(Events.TOOGLE_DICTIONARY_PANEL, this);
    }//GEN-LAST:event_labelDictionaryActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private wl.ui.ButtonLabel labelBookmark;
    private wl.ui.ButtonLabel labelConfig;
    private wl.ui.ButtonLabel labelDictionary;
    private wl.ui.ButtonLabel labelNote;
    private wl.ui.ButtonLabel labelSinc;
    private wl.ui.ButtonLabel labelViewMode;
    // End of variables declaration//GEN-END:variables



    

}
